package persistence

import (
	"Data-API-MCP/backend/internal/domain/entity"
	"Data-API-MCP/backend/internal/domain/repository"
	"context"
	"encoding/json"

	"gorm.io/gorm"
)

// MCPServiceRepositoryImpl MCP服务仓储实现
type MCPServiceRepositoryImpl struct {
	db *gorm.DB
}

// NewMCPRepository 创建MCP服务仓储实例
func NewMCPRepository(db *gorm.DB) repository.MCPServiceRepository {
	return &MCPServiceRepositoryImpl{
		db: db,
	}
}

// CreateService 创建MCP服务
func (r *MCPServiceRepositoryImpl) CreateService(ctx context.Context, service *entity.MCPService) error {
	return r.db.WithContext(ctx).Create(service).Error
}

// GetService 获取MCP服务
func (r *MCPServiceRepositoryImpl) GetService(ctx context.Context, id int64) (*entity.MCPService, error) {
	var service entity.MCPService
	err := r.db.WithContext(ctx).First(&service, id).Error
	return &service, err
}

// ListServices 获取MCP服务列表
func (r *MCPServiceRepositoryImpl) ListServices(ctx context.Context) ([]*entity.MCPService, error) {
	var services []*entity.MCPService
	err := r.db.WithContext(ctx).Find(&services).Error
	return services, err
}

// UpdateService 更新MCP服务
func (r *MCPServiceRepositoryImpl) UpdateService(ctx context.Context, service *entity.MCPService) error {
	return r.db.WithContext(ctx).Save(service).Error
}

// DeleteService 删除MCP服务
func (r *MCPServiceRepositoryImpl) DeleteService(ctx context.Context, id int64) error {
	return r.db.WithContext(ctx).Delete(&entity.MCPService{}, id).Error
}

// GetServiceStatus 获取服务状态
func (r *MCPServiceRepositoryImpl) GetServiceStatus(ctx context.Context, id int64) (*entity.ServiceStatus, error) {
	var status entity.ServiceStatus
	err := r.db.WithContext(ctx).Table("service_statuses").Where("service_id = ?", id).First(&status).Error
	return &status, err
}

// GetServiceMetrics 获取服务指标
func (r *MCPServiceRepositoryImpl) GetServiceMetrics(ctx context.Context, id int64) (*entity.ServiceMetrics, error) {
	var metrics entity.ServiceMetrics
	err := r.db.WithContext(ctx).Table("service_metrics").Where("service_id = ?", id).First(&metrics).Error
	return &metrics, err
}

// GetServiceLogs 获取服务日志
func (r *MCPServiceRepositoryImpl) GetServiceLogs(ctx context.Context, id int64) ([]*entity.ServiceLog, error) {
	var logs []*entity.ServiceLog
	err := r.db.WithContext(ctx).Where("service_id = ?", id).Order("created_at DESC").Find(&logs).Error
	return logs, err
}

// GetServiceConfig 获取服务配置
func (r *MCPServiceRepositoryImpl) GetServiceConfig(ctx context.Context, id int64) (map[string]interface{}, error) {
	var service entity.MCPService
	err := r.db.WithContext(ctx).First(&service, id).Error
	if err != nil {
		return nil, err
	}

	var config map[string]interface{}
	if service.Config == "" {
		return make(map[string]interface{}), nil
	}
	err = json.Unmarshal([]byte(service.Config), &config)
	return config, err
}

// UpdateServiceConfig 更新服务配置
func (r *MCPServiceRepositoryImpl) UpdateServiceConfig(ctx context.Context, id int64, config map[string]interface{}) error {
	configJSON, err := json.Marshal(config)
	if err != nil {
		return err
	}

	return r.db.WithContext(ctx).Model(&entity.MCPService{}).Where("id = ?", id).Update("config", string(configJSON)).Error
}

// ReloadService 重载服务配置
func (r *MCPServiceRepositoryImpl) ReloadService(ctx context.Context, id int64) error {
	// 这里可以实现重载服务的具体逻辑
	// 例如：调用服务管理系统的API来重载服务
	return nil
}

// CreateServiceParam 创建服务参数
func (r *MCPServiceRepositoryImpl) CreateServiceParam(ctx context.Context, param *entity.MCPServiceParam) error {
	return r.db.WithContext(ctx).Create(param).Error
}

// GetServiceParams 获取服务参数列表
func (r *MCPServiceRepositoryImpl) GetServiceParams(ctx context.Context, serviceID string) ([]*entity.MCPServiceParam, error) {
	var params []*entity.MCPServiceParam
	err := r.db.WithContext(ctx).Where("service_id = ?", serviceID).Find(&params).Error
	return params, err
}

// UpdateServiceParam 更新服务参数
func (r *MCPServiceRepositoryImpl) UpdateServiceParam(ctx context.Context, param *entity.MCPServiceParam) error {
	return r.db.WithContext(ctx).Save(param).Error
}

// DeleteServiceParam 删除服务参数
func (r *MCPServiceRepositoryImpl) DeleteServiceParam(ctx context.Context, id string) error {
	return r.db.WithContext(ctx).Delete(&entity.MCPServiceParam{}, id).Error
}

// CreateServiceVersion 创建服务版本
func (r *MCPServiceRepositoryImpl) CreateServiceVersion(ctx context.Context, version *entity.MCPServiceVersion) error {
	return r.db.WithContext(ctx).Create(version).Error
}

// GetServiceVersion 获取服务版本
func (r *MCPServiceRepositoryImpl) GetServiceVersion(ctx context.Context, id string) (*entity.MCPServiceVersion, error) {
	var version entity.MCPServiceVersion
	err := r.db.WithContext(ctx).First(&version, "id = ?", id).Error
	return &version, err
}

// GetServiceVersions 获取服务版本列表
func (r *MCPServiceRepositoryImpl) GetServiceVersions(ctx context.Context, serviceID string) ([]*entity.MCPServiceVersion, error) {
	var versions []*entity.MCPServiceVersion
	err := r.db.WithContext(ctx).Where("service_id = ?", serviceID).Find(&versions).Error
	return versions, err
}

// UpdateServiceVersion 更新服务版本
func (r *MCPServiceRepositoryImpl) UpdateServiceVersion(ctx context.Context, version *entity.MCPServiceVersion) error {
	return r.db.WithContext(ctx).Save(version).Error
}

// DeleteServiceVersion 删除服务版本
func (r *MCPServiceRepositoryImpl) DeleteServiceVersion(ctx context.Context, id string) error {
	return r.db.WithContext(ctx).Delete(&entity.MCPServiceVersion{}, id).Error
}

// ActivateServiceVersion 激活服务版本
func (r *MCPServiceRepositoryImpl) ActivateServiceVersion(ctx context.Context, serviceID, versionID string) error {
	// 开启事务
	return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		// 1. 将当前激活的版本设置为非激活
		if err := tx.Model(&entity.MCPServiceVersion{}).
			Where("service_id = ? AND is_active = ?", serviceID, true).
			Update("is_active", false).Error; err != nil {
			return err
		}

		// 2. 激活指定版本
		if err := tx.Model(&entity.MCPServiceVersion{}).
			Where("id = ?", versionID).
			Update("is_active", true).Error; err != nil {
			return err
		}

		// 3. 更新服务的当前版本ID
		if err := tx.Model(&entity.MCPService{}).
			Where("id = ?", serviceID).
			Update("current_version_id", versionID).Error; err != nil {
			return err
		}

		return nil
	})
}
